package cn.grayrelese.rule;

import com.netflix.loadbalancer.Server;
import com.netflix.loadbalancer.ZoneAvoidanceRule;
import com.netflix.niws.loadbalancer.DiscoveryEnabledServer;
import com.netflix.zuul.context.RequestContext;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import static cn.grayrelese.response.CustomResponse.responseServiceMessages;

/**
 * 灰度自定义路由规则
 */
public class GrayMetadataRule extends ZoneAvoidanceRule {
    @Autowired
    Environment env;
//    Logger logger = LoggerFactory.getLogger(GrayMetadataRule.class);
    public static final String KEY_VERSION = "version";
    @Override
    public Server choose(Object key) {
        //1.从请求头获取version信息
        RequestContext ctx = RequestContext.getCurrentContext();
        HttpServletRequest request = ctx.getRequest();
        String version = (String) request.getAttribute(KEY_VERSION);
        //2.获取服务实例列表
        List<Server> serverList =this.getPredicate().getEligibleServers(this.getLoadBalancer().getAllServers(), key);
        //3.循环serverList，选择version匹配的服务并返回
        List<Server> notVersionSeverList = new ArrayList<>();
        List<Server> versionSeverList = new ArrayList<>();
        for (Server server : serverList) {
            Map<String, String> metadata = ((DiscoveryEnabledServer) server).getInstanceInfo().getMetadata();
            String metaVersion = metadata.get(KEY_VERSION);
            if (!StringUtils.isEmpty(metaVersion)) {
                if (metaVersion.equals(version)) {
                    versionSeverList.add(server);
                    continue;
                }
            }
            else {
                notVersionSeverList.add(server);
            }
        }
        Server s = null;
        try{
            if(!versionSeverList.isEmpty()&&versionSeverList.size()!=0) {
                //轮询获取灰度主机
                s = getPredicate().chooseRoundRobinAfterFiltering(versionSeverList).get();
            }else {
                //轮询获取灰度主机
                s = getPredicate().chooseRoundRobinAfterFiltering(notVersionSeverList).get();
            }
        }catch (IllegalStateException e){
            //设置无主机相应
            HttpServletResponse response = ctx.getResponse();
            responseServiceMessages(response,env,String.format("没有可用的服务器!"));
        }
        return s;
    }
  }
